package com.example.mapstruct;

import java.util.HashMap;
import java.util.Map;
import java.util.TreeSet;

/**
 * @author ayatsuji
 * @date 2022-07-24 22:20
 * @since
 */
public class Main {
    public static void main(String[] args) {
        String[] foods = {"emgqdbo","jmvfxjohq","qnvseohnoe","yhptazyko","ocqmvmwjq"};
        String[] cuisines = {"snaxol","snaxol","snaxol","fajbervsj","fajbervsj"};
        int[] ratings = {2,6,18,6,5};
        FoodRatings foodRatings = new FoodRatings(foods, cuisines, ratings);
        // "changeRating","highestRated","changeRating","changeRating","changeRating","highestRated","highestRated"
        foodRatings.changeRating("qnvseohnoe",11);
        foodRatings.highestRated("fajbervsj");
        foodRatings.changeRating("emgqdbo",3);
        foodRatings.changeRating("jmvfxjohq",9);
        foodRatings.changeRating("emgqdbo",14);
        foodRatings.highestRated("fajbervsj");
        String s = foodRatings.highestRated("snaxol");
        System.out.println(s);
    }
}

class FoodRatings {
    private Map<String, TreeSet<FoodRating>> foodRatings;
    private Map<String, String> foodsCuisinesMap;
    private Map<String, FoodRating> foodRatingMap;

    public FoodRatings(String[] foods, String[] cuisines, int[] ratings) {
        foodRatings = new HashMap<>();
        foodsCuisinesMap = new HashMap<>();
        foodRatingMap = new HashMap<>();
        for (int i = 0; i < cuisines.length; i++) {
            TreeSet<FoodRating> set = foodRatings.getOrDefault(cuisines[i], new TreeSet<>());
            final FoodRating foodRating = new FoodRating(foods[i], ratings[i]);
            set.add(foodRating);
            foodRatings.put(cuisines[i], set);
            foodsCuisinesMap.put(foods[i], cuisines[i]);
            foodRatingMap.put(foods[i], foodRating);
        }

    }

    public void changeRating(String food, int newRating) {
        String cuisine = foodsCuisinesMap.get(food);
        final FoodRating foodRating = foodRatingMap.get(food);
        final TreeSet<FoodRating> foodRatings = this.foodRatings.get(cuisine);
        foodRatings.remove(foodRating);
        foodRating.setRating(newRating);
        foodRatings.add(foodRating);
    }

    public String highestRated(String cuisine) {
        return foodRatings.get(cuisine).first().getFood();
    }

    static class FoodRating implements Comparable<FoodRating> {
        private String food;
        private int rating;

        public FoodRating(String food, int rating) {
            this.food = food;
            this.rating = rating;
        }

        public String getFood() {
            return this.food;
        }

        public void setRating(int rating) {
            this.rating = rating;
        }

        public boolean equals(Object o) {
            return this.food.equals(((FoodRating) o).food);
        }

        public int hashCode() {
            return food.hashCode();
        }

        public int compareTo(FoodRating f) {
            return (this.rating - f.rating) == 0 ? this.food.compareTo(f.food) : -(this.rating - f.rating);
        }
    }
}